package com.artfii;

import com.google.common.collect.Range;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;
import org.joda.time.DateTime;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * 分表策略及算法（本例是按年份分表）
 * @author leeton
 * @date : 2020-12-08
 */
public class ShardingAlgorithm implements PreciseShardingAlgorithm<Date>, RangeShardingAlgorithm<Date> {

    /**
     * SQL: WHERE 的时间条件是 = 的情况
     * @param collection 返回的分表名称集合
     * @param preciseShardingValue 精确的分表值
     * @return
     */
    @Override
    public String doSharding(Collection collection, PreciseShardingValue preciseShardingValue) {
        String v = preciseShardingValue.getValue().toString();
        int year = Integer.valueOf(v.substring(0, 4));
        return preciseShardingValue.getLogicTableName() + "_" + year;
    }

    /**
     * SQL: WHERE 的时间条件是 => <= 或 between on 的情况
     * @param collection 返回的分表名称集合
     * @param rangeShardingValue 范围分表值
     * @return
     */
    @Override
    public Collection<String> doSharding(Collection collection, RangeShardingValue rangeShardingValue) {

        List<String> searchTables = new ArrayList<>(collection.size());
        Range ranges = rangeShardingValue.getValueRange();

        DateTime startTime = null;
        DateTime endTime = null;
        if (ranges.hasLowerBound()) {// 有下边界(开始时间)
            startTime = DateUtil.ToJodaDate(ranges.lowerEndpoint().toString());
        }else{//没有开始时间，则开始时间设置为最小表的最小天数
            String begingTable = (collection.toArray()[0]).toString();
            int lastOf = begingTable.lastIndexOf("_")+1;
            String year =begingTable.substring(lastOf,lastOf+4);
            startTime = DateUtil.ToJodaDate(year+"0101").secondOfDay().withMinimumValue().toDateTime();
        }
        if (ranges.hasUpperBound()) {// 有上边界(结束时间)
            endTime = DateUtil.ToJodaDate(ranges.upperEndpoint().toString());
        }else {//没有结束时间，则结束时间设置为最大表的最大天数
            int size = collection.size();
            String lastTable = (collection.toArray()[size - 1]).toString();
            int lastOf = lastTable.lastIndexOf("_")+1;
            String year =lastTable.substring(lastOf,lastOf+4);
            endTime = DateUtil.ToJodaDate(year+"1230").dayOfMonth().withMaximumValue().toDateTime();
        }

        while (startTime.isBefore(endTime)) {
            searchTables.add(rangeShardingValue.getLogicTableName() + "_" + startTime.toString("yyyy"));
            startTime = startTime.plusYears(1);
        }
        return searchTables;
    }



}